#include "thread_pool.h"
#include <iostream>

namespace zh
{
    ThreadPool::ThreadPool(size_t threadCount) : m_runing(true)
    {
        m_threads.resize(threadCount);
        for (size_t i = 0; i < threadCount; ++i)
        {
            m_threads[i] = std::make_shared<std::thread>(std::bind(&ThreadPool::doTask, this));
        }
    }

    ThreadPool::~ThreadPool()
    {
        stop();
        for (auto thread : m_threads)
        {
            if (thread->joinable())
            {
                thread->join();
            }
        }
    }

    void ThreadPool::doTask()
    {
        while (m_runing)
        {
            Task task;
            {
                std::unique_lock<std::mutex> lock(m_mutex);
                m_condition.wait(lock, [&] { return !m_tasks.empty() || !m_runing; });
                if (!m_runing && m_tasks.empty())
                {
                    return;
                }
                task = m_tasks.front();
                m_tasks.pop();
            }
            task();
        }
    }

    void ThreadPool::submitTask(const Task& task)
    {
        {
            std::lock_guard<std::mutex> lock(m_mutex);
            m_tasks.push(task);
        }
        m_condition.notify_one();
    }

    void ThreadPool::start()
    {
        m_runing = true;
        m_condition.notify_all();
    }

    void ThreadPool::stop()
    {
        m_runing = false;
        m_condition.notify_all();
    }

    size_t ThreadPool::getThreadCount() const
    {
        return m_threads.size();
    }
} // namespace zh
